﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Borg.Properties;

namespace Borg
{
    [Serializable]
    public class MetaElementCollection<T> : IEnumerable<T>
        where T : MetaElement
    {
        private readonly List<T> _list;

        internal List<T> List
        {
            get { return _list; }
        }

        public T this[string name]
        {
            get
            {
                foreach (var obj in _list.Where(obj => obj.Name == name))
                    return obj;

                throw new ArgumentException(
                    string.Format(
                        Exceptions.Meta_element_not_found,
                        name),
                    "name");
            }
        }

        public T this[int index]
        {
            get { return _list[index]; }
        }

        public int Count
        {
            get { return _list.Count; }
        }

        public bool IsReadOnly
        {
            get { return true; }
        }

        internal MetaElementCollection()
        {
            _list = new List<T>();
        }

        internal MetaElementCollection(IEnumerable<T> elements)
        {
            _list = new List<T>(elements);
        }

        internal MetaElementCollection(int capacity)
        {
            _list = new List<T>(capacity);
        }

        public bool Contains(T element)
        {
            return _list.Contains(element);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            _list.CopyTo(array, arrayIndex);
        }

        public bool Contains(string name)
        {
            return _list.Any(obj => obj.Name == name);
        }

        public T GetById(int id)
        {
            return _list.First(element => element.Id == id);
        }

        public T[] ToArray()
        {
            return _list.ToArray();
        }

        public IEnumerator<T> GetEnumerator()
        {
            return ((IEnumerable<T>)ToArray()).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public override string ToString()
        {
            return _list.ToString();
        }

        internal void Add(T element)
        {
            _list.Add(element);
        }

        internal void Clear()
        {
            _list.Clear();
        }

        internal bool Remove(T element)
        {
            return _list.Remove(element);
        }
    }
}
